<template>
  <!-- 模板部分保持不变 -->
  <div class="intercom-container">
    <h2>SIP对讲系统</h2>

    <!-- 状态显示 -->
    <div class="status-panel">
      <div class="status-item">
        <span>连接状态：</span>
        <span :class="['status-dot', connectionStatus]"></span>
        {{ connectionStatusText }}
      </div>
      <div class="status-item">
        <span>注册状态：</span>
        <span :class="['status-dot', registrationStatus]"></span>
        {{ registrationStatusText }}
      </div>
      <div class="status-item" v-if="callStatus !== 'idle'">
        <span>通话状态：</span>
        <span class="call-status">{{ callStatusText }}</span>
      </div>
    </div>

    <!-- 服务器配置 -->
    <div class="config-panel">
      <h3>服务器配置</h3>
      <div class="input-group">
        <label for="server">服务器地址：</label>
        <input
          id="server"
          v-model="server"
          type="text"
          placeholder="wss://your-sip-server.com:7443"
          :disabled="isConnected"
        />
      </div>
      <div class="input-group">
        <label for="username">用户名：</label>
        <input
          id="username"
          v-model="username"
          type="text"
          placeholder="1003"
          :disabled="isConnected"
        />
      </div>
      <div class="input-group">
        <label for="password">密码：</label>
        <input
          id="password"
          v-model="password"
          type="password"
          placeholder="输入SIP密码"
          :disabled="isConnected"
        />
      </div>
      <div class="input-group">
        <label for="domain">域名：</label>
        <input
          id="domain"
          v-model="domain"
          type="text"
          placeholder="172.16.49.121"
          :disabled="isConnected"
        />
      </div>
    </div>

    <!-- 来电显示 -->
    <div v-if="incomingCall" class="incoming-call-alert">
      <div class="call-alert-content">
        <h3>来电中...</h3>
        <p>来自: {{ incomingCaller }}</p>
        <div class="call-actions">
          <button @click="answerCall" class="btn-answer">接听</button>
          <button @click="rejectCall" class="btn-reject">拒绝</button>
        </div>
      </div>
    </div>

    <!-- 控制面板 -->
    <div class="control-panel">
      <div class="input-group">
        <label for="targetNumber">目标号码：</label>
        <input
          id="targetNumber"
          v-model="targetNumber"
          type="text"
          placeholder="输入对讲号码"
          :disabled="isInCall"
        />
      </div>

      <div class="button-group">
        <button
          @click="connect"
          :disabled="isConnected || !server || !username || !password"
          class="btn-connect"
        >
          连接服务器
        </button>

        <button
          @click="registerSip"
          :disabled="!isConnected || isRegistered"
          class="btn-register"
        >
          注册SIP
        </button>

        <button
          @click="makeCall"
          :disabled="!isRegistered || isInCall || !targetNumber"
          class="btn-call"
        >
          发起对讲
        </button>

        <button @click="hangupCall" :disabled="!isInCall" class="btn-hangup">
          结束对讲
        </button>

        <button
          @click="unregister"
          :disabled="!isRegistered"
          class="btn-unregister"
        >
          注销
        </button>
      </div>
    </div>

    <!-- 音频控制面板 -->
    <div class="audio-panel" v-if="isInCall">
      <h4>音频控制</h4>
      <div class="audio-controls">
        <audio ref="remoteAudio" autoplay controls></audio>
        <button @click="toggleAudioMute" class="btn-mute">
          {{ isAudioMuted ? "取消静音" : "静音" }}
        </button>
        <button @click="toggleAudioOutput" class="btn-output">
          切换音频输出
        </button>
      </div>
    </div>

    <!-- 通话计时 -->
    <div v-if="isInCall" class="call-timer">通话时长: {{ callDuration }}</div>

    <!-- 日志输出 -->
    <div class="log-panel">
      <h4>系统日志</h4>
      <div class="log-content">
        <div
          v-for="(log, index) in logs"
          :key="index"
          :class="['log-item', log.type]"
        >
          [{{ log.time }}] {{ log.message }}
        </div>
      </div>
      <button @click="clearLogs" class="btn-clear">清空日志</button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, nextTick } from "vue";
import * as SIP from "sip.js";

// 响应式数据
const connectionStatus = ref("disconnected");
const registrationStatus = ref("unregistered");
const callStatus = ref("idle");
const isInCall = ref(false);
const incomingCall = ref(false);
const incomingCaller = ref("");
const targetNumber = ref("1004");
const callStartTime = ref(null);
const callDuration = ref("00:00");
const logs = ref([]);
const remoteAudio = ref(null);
const userAgent = ref(null);
const registerer = ref(null);
const isAudioMuted = ref(false);
const audioOutputIndex = ref(0);
const audioOutputs = ref([]);

// 服务器配置
const server = ref("wss://172.16.49.121:7443");
const username = ref("1003");
const password = ref("112233");
const domain = ref("172.16.49.121");

// 计算属性
const connectionStatusText = computed(() => {
  const statusMap = {
    disconnected: "未连接",
    connecting: "连接中...",
    connected: "已连接",
  };
  return statusMap[connectionStatus.value];
});

const registrationStatusText = computed(() => {
  const statusMap = {
    unregistered: "未注册",
    registering: "注册中...",
    registered: "已注册",
  };
  return statusMap[registrationStatus.value];
});

const callStatusText = computed(() => {
  const statusMap = {
    idle: "空闲",
    calling: "呼叫中...",
    ringing: "振铃中...",
    answered: "已接通",
    ended: "通话结束",
  };
  return statusMap[callStatus.value];
});

const isConnected = computed(() => connectionStatus.value === "connected");
const isRegistered = computed(() => registrationStatus.value === "registered");

// 日志记录
const addLog = (message, type = "info") => {
  const time = new Date().toLocaleTimeString();
  logs.value.unshift({ time, message, type });
  console.log(`[${type}] ${message}`);
};

// 音频控制
const toggleAudioMute = () => {
  if (remoteAudio.value) {
    remoteAudio.value.muted = !remoteAudio.value.muted;
    isAudioMuted.value = remoteAudio.value.muted;
    addLog(`音频${isAudioMuted.value ? "已静音" : "已取消静音"}`, "info");
  }
};

const toggleAudioOutput = async () => {
  if (!remoteAudio.value) return;

  try {
    const devices = await navigator.mediaDevices.enumerateDevices();
    const audioOutputsList = devices.filter(
      (device) => device.kind === "audiooutput"
    );

    if (audioOutputsList.length > 0) {
      audioOutputIndex.value =
        (audioOutputIndex.value + 1) % audioOutputsList.length;
      const deviceId = audioOutputsList[audioOutputIndex.value].deviceId;

      await remoteAudio.value.setSinkId(deviceId);
      addLog(
        `音频输出已切换到: ${
          audioOutputsList[audioOutputIndex.value].label ||
          "设备 " + (audioOutputIndex.value + 1)
        }`,
        "info"
      );
    }
  } catch (error) {
    addLog(`切换音频输出失败: ${error.message}`, "error");
  }
};

// 连接服务器
const connect = async () => {
  try {
    connectionStatus.value = "connecting";
    addLog("正在连接SIP服务器...", "info");

    // 创建正确的URI
    const uri = SIP.UserAgent.makeURI(`sip:${username.value}@${domain.value}`);

    if (!uri) {
      throw new Error("无效的SIP URI");
    }

    // 创建UserAgent，强制使用正确的Contact头
    userAgent.value = new SIP.UserAgent({
      uri,
      viaHost: localIP.value,
      transportOptions: {
        server: server.value,
      },
      authorizationUsername: username.value,
      authorizationPassword: password.value,
      sessionDescriptionHandlerOptions: {
        constraints: {
          audio: true,
          video: false,
        },
      },
      // 强制使用正确的Contact参数
      contactName: username.value,
      contactParams: {
        transport: "ws",
        host: localIP.value,
        port: "7443",
      },
      // 委托配置
      delegate: {
        onInvite: (invitation) => {
          console.log("收到来电", invitation);
          addLog("收到来电", "incoming");
          incomingCall.value = true;
          incomingCaller.value =
            invitation.remoteIdentity.uri.user || "未知号码";
          callStatus.value = "ringing";
          currentInvitation.value = invitation;
          if (invitation && invitation.request) {
            const rawMessage = invitation.request.toString();
            // console.log("原始INVITE内容999:", rawMessage);
            if (rawMessage.includes("answer-after=0")) {
              //自动接听
              isAutoAnswer.value = true;
              console.log("原始INVITE内容999:", rawMessage);
              answerCall();
            } else {
              isAutoAnswer.value = false;
              laidianFlag.value = true;
            }
          } else {
            console.error("无法获取原始消息 - invitation.request 不存在");
          }

          // 监听邀请状态变化
          invitation.stateChange.addListener((state) => {
            if (state === SIP.SessionState.Established) {
              // 通话建立后设置音频
              setTimeout(() => {
                setupRemoteAudio(invitation);
              }, 500);
            } else if (state === SIP.SessionState.Terminated) {
              // 通话被对方挂断
              handleCallEnded("对方已挂断通话");
            }
          });
        },
      },
    });

    // 创建注册器
    registerer.value = new SIP.Registerer(userAgent.value);

    // 监听注册状态
    registerer.value.stateChange.addListener((state) => {
      if (state === SIP.RegistererState.Registered) {
        registrationStatus.value = "registered";
        addLog("SIP注册成功", "success");
      } else if (state === SIP.RegistererState.Unregistered) {
        registrationStatus.value = "unregistered";
        addLog("SIP已注销", "info");
      }
    });

    // 重写注册器的register方法，强制使用正确的Contact头
    const originalRegister = registerer.value.register.bind(registerer.value);
    registerer.value.register = async (options = {}) => {
      options.extraHeaders = options.extraHeaders || [];
      options.extraHeaders.push(
        `Contact: <sip:${username.value}@${domain.value};transport=ws>`
      );

      return originalRegister(options);
    };

    // 启动UserAgent
    await userAgent.value.start();
    connectionStatus.value = "connected";
    addLog("SIP服务器连接成功", "success");

    // 注册SIP
    await registerSip();
  } catch (error) {
    connectionStatus.value = "disconnected";
    addLog(`连接失败: ${error.message}`, "error");
    console.error("连接错误详情:", error);
  }
};

// 注册SIP
const registerSip = async () => {
  try {
    if (!userAgent.value || !registerer.value) {
      addLog("SIP客户端未初始化", "error");
      return;
    }

    registrationStatus.value = "registering";
    addLog("正在注册SIP账号...", "info");

    const options = {
      extraHeaders: [
        `Contact: <sip:${username.value}@${domain.value};transport=ws>`,
      ],
    };

    await registerer.value.register(options);
  } catch (error) {
    registrationStatus.value = "unregistered";
    addLog(`SIP注册失败: ${error.message}`, "error");
    console.error("注册错误详情:", error);
  }
};

// 发起呼叫
const makeCall = async () => {
  if (!targetNumber.value) {
    addLog("请输入目标号码", "warning");
    return;
  }

  try {
    if (!userAgent.value) {
      addLog("SIP客户端未初始化", "error");
      return;
    }

    callStatus.value = "calling";
    addLog(`正在呼叫 ${targetNumber.value}...`, "info");

    const targetUri = SIP.UserAgent.makeURI(
      `sip:${targetNumber.value}@${domain.value}`
    );

    if (!targetUri) {
      throw new Error("无效的目标SIP URI");
    }

    // 创建邀请
    const inviter = new SIP.Inviter(userAgent.value, targetUri, {
      sessionDescriptionHandlerOptions: {
        constraints: {
          audio: true,
          video: false,
        },
      },
    });

    // 监听邀请状态
    inviter.stateChange.addListener((state) => {
      addLog(`邀请状态: ${state}`, "info");

      if (state === SIP.SessionState.Established) {
        callStatus.value = "answered";
        isInCall.value = true;
        startCallTimer();
        addLog("通话已接通", "success");

        // 通话建立后设置音频，添加延迟确保一切就绪
        setTimeout(() => {
          setupRemoteAudio(inviter);
        }, 500);
      } else if (state === SIP.SessionState.Terminated) {
        // 通话被对方挂断或异常结束
        handleCallEnded("通话已结束");
      }
    });

    // 发送邀请
    await inviter.invite();

    currentSession.value = inviter;
  } catch (error) {
    callStatus.value = "idle";
    addLog(`呼叫失败: ${error.message}`, "error");
  }
};

// 设置远程音频流 - 改进版本
const setupRemoteAudio = (session) => {
  // 确保DOM已更新
  nextTick(() => {
    if (!session) {
      addLog("会话未就绪", "warning");
      return;
    }

    if (!remoteAudio.value) {
      addLog("音频元素未就绪，等待重试...", "warning");
      // 重试机制
      setTimeout(() => {
        setupRemoteAudio(session);
      }, 300);
      return;
    }

    try {
      // 获取会话描述处理器
      const sessionDescriptionHandler = session.sessionDescriptionHandler;

      if (!sessionDescriptionHandler) {
        addLog("会话描述处理器未找到，等待重试...", "warning");
        setTimeout(() => {
          setupRemoteAudio(session);
        }, 300);
        return;
      }

      // 获取对等连接
      const peerConnection = sessionDescriptionHandler.peerConnection;

      if (!peerConnection) {
        addLog("对等连接未建立，等待重试...", "warning");
        setTimeout(() => {
          setupRemoteAudio(session);
        }, 300);
        return;
      }

      // 方法1: 监听远程流事件
      peerConnection.ontrack = (event) => {
        if (event.streams && event.streams[0]) {
          const remoteStream = event.streams[0];
          remoteAudio.value.srcObject = remoteStream;

          remoteAudio.value.play().catch((e) => {
            addLog(`播放音频失败: ${e.message}`, "error");
          });

          addLog("通过ontrack事件接收到远程音频流", "success");
        }
      };

      // 方法2: 检查现有的接收器
      const receivers = peerConnection.getReceivers();
      const remoteTracks = receivers
        .filter((receiver) => receiver.track && receiver.track.kind === "audio")
        .map((receiver) => receiver.track);

      if (remoteTracks.length > 0) {
        const combinedStream = new MediaStream(remoteTracks);
        remoteAudio.value.srcObject = combinedStream;

        remoteAudio.value.play().catch((e) => {
          addLog(`播放音频失败: ${e.message}`, "error");
        });

        addLog("通过现有接收器获取到远程音频流", "success");
        return;
      }

      // 方法3: 尝试从会话描述处理器获取远程流
      try {
        const remoteMediaStream =
          sessionDescriptionHandler.getRemoteMediaStream();
        if (remoteMediaStream) {
          remoteAudio.value.srcObject = remoteMediaStream;

          remoteAudio.value.play().catch((e) => {
            addLog(`播放音频失败: ${e.message}`, "error");
          });

          addLog("通过getRemoteMediaStream获取到远程音频流", "success");
          return;
        }
      } catch (error) {
        // 忽略此错误，继续尝试其他方法
      }

      // 如果以上方法都失败，设置重试
      addLog("未找到远程音频流，将在500ms后重试", "warning");
      setTimeout(() => {
        setupRemoteAudio(session);
      }, 500);
    } catch (error) {
      addLog(`设置远程音频失败: ${error.message}`, "error");
      console.error("音频设置错误详情:", error);

      // 错误时也重试
      setTimeout(() => {
        setupRemoteAudio(session);
      }, 500);
    }
  });
};

// 处理通话结束 - 新增函数
const handleCallEnded = (reason = "通话已结束") => {
  addLog(reason, "info");

  callStatus.value = "ended";
  isInCall.value = false;
  incomingCall.value = false;
  stopCallTimer();
  cleanupAudio();

  // 清理当前会话
  currentSession.value = null;
  currentInvitation.value = null;

  // 3秒后重置状态
  setTimeout(() => {
    callStatus.value = "idle";
  }, 3000);
};

// 清理音频
const cleanupAudio = () => {
  if (remoteAudio.value) {
    remoteAudio.value.srcObject = null;
    remoteAudio.value.pause();
  }
};

// 接听来电
const answerCall = async () => {
  try {
    if (!currentInvitation.value) {
      addLog("没有待接听的来电", "error");
      return;
    }

    addLog("正在接听来电...", "info");

    const options = {
      sessionDescriptionHandlerOptions: {
        constraints: {
          audio: true,
          video: false,
        },
      },
    };

    await currentInvitation.value.accept(options);

    incomingCall.value = false;
    isInCall.value = true;
    callStatus.value = "answered";
    startCallTimer();
    addLog("来电已接听", "success");

    currentSession.value = currentInvitation.value;
    currentInvitation.value = null;
  } catch (error) {
    addLog(`接听失败: ${error.message}`, "error");
    incomingCall.value = false;
  }
};

// 拒绝来电
const rejectCall = async () => {
  try {
    if (currentInvitation.value) {
      await currentInvitation.value.reject();
      addLog("来电已拒绝", "info");
    }
  } catch (error) {
    addLog(`拒绝来电失败: ${error.message}`, "error");
  } finally {
    incomingCall.value = false;
    callStatus.value = "idle";
    currentInvitation.value = null;
  }
};

// 挂断通话
const hangupCall = async () => {
  try {
    if (currentSession.value) {
      await currentSession.value.bye();
      addLog("通话已挂断", "info");
    }
  } catch (error) {
    addLog(`挂断失败: ${error.message}`, "error");
  } finally {
    handleCallEnded("通话已挂断");
  }
};

// 注销SIP
const unregister = async () => {
  try {
    if (registerer.value) {
      await registerer.value.unregister();
      registrationStatus.value = "unregistered";
      addLog("SIP注销成功", "success");
    }
  } catch (error) {
    addLog(`注销失败: ${error.message}`, "error");
  }
};

// 通话计时器
let callTimer = null;
const startCallTimer = () => {
  callStartTime.value = new Date();
  callTimer = setInterval(() => {
    const now = new Date();
    const duration = Math.floor((now - callStartTime.value) / 1000);
    const minutes = Math.floor(duration / 60)
      .toString()
      .padStart(2, "0");
    const seconds = (duration % 60).toString().padStart(2, "0");
    callDuration.value = `${minutes}:${seconds}`;
  }, 1000);
};

const stopCallTimer = () => {
  if (callTimer) {
    clearInterval(callTimer);
    callTimer = null;
  }
  callDuration.value = "00:00";
};

// 清空日志
const clearLogs = () => {
  logs.value = [];
};

// 当前会话和邀请
const currentSession = ref(null);
const currentInvitation = ref(null);

// 断开连接
const disconnect = async () => {
  if (currentSession.value) {
    await currentSession.value.bye();
  }

  if (registerer.value) {
    await registerer.value.unregister();
  }

  if (userAgent.value) {
    await userAgent.value.stop();
  }

  connectionStatus.value = "disconnected";
  registrationStatus.value = "unregistered";
  callStatus.value = "idle";
  isInCall.value = false;
  incomingCall.value = false;
  stopCallTimer();
  cleanupAudio();

  addLog("已断开所有连接", "info");
};

// 获取本机IP
const localIP = ref("");

const getLocalIP = () => {
  return new Promise((resolve, reject) => {
    window.RTCPeerConnection =
      window.RTCPeerConnection ||
      window.mozRTCPeerConnection ||
      window.webkitRTCPeerConnection;

    if (!window.RTCPeerConnection) {
      reject("您的浏览器不支持WebRTC API");
      return;
    }

    const pc = new RTCPeerConnection({ iceServers: [] });
    pc.createDataChannel("");
    pc.createOffer().then((offer) => pc.setLocalDescription(offer));

    pc.onicecandidate = (event) => {
      if (event.candidate) {
        const ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/;
        const ipMatch = event.candidate.candidate.match(ipRegex);
        if (ipMatch) {
          resolve(ipMatch[1]);
          pc.onicecandidate = null;
        }
      }
    };

    setTimeout(() => {
      resolve("127.0.0.1");
    }, 1000);
  });
};

// 生命周期
onMounted(async () => {
  addLog("对讲系统已初始化", "info");
  try {
    localIP.value = await getLocalIP();
    addLog(`检测到本机IP: ${localIP.value}`, "info");
  } catch (error) {
    console.error("获取IP地址失败:", error);
    localIP.value = "127.0.0.1";
    addLog(`获取本机IP失败，使用默认值: ${localIP.value}`, "warning");
    nextTick(() => {
      connect();
    });
  }
  nextTick(() => {
    connect();
  });
});

onBeforeUnmount(() => {
  disconnect();
});
</script>

<style scoped>
/* 样式保持不变 */
.intercom-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
  height: 766px;
  overflow-y: auto;
}

.status-panel {
  background: #f5f5f5;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 20px;
}

.status-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 8px;
}

.status-dot.connected,
.status-dot.registered {
  background: #4caf50;
}

.status-dot.disconnected,
.status-dot.unregistered {
  background: #f44336;
}

.status-dot.connecting,
.status-dot.registering {
  background: #ff9800;
}

.call-status {
  color: #2196f3;
  font-weight: bold;
}

.config-panel {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}

.config-panel h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #333;
}

.incoming-call-alert {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #ffeb3b;
  padding: 30px;
  border-radius: 10px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  text-align: center;
}

.call-alert-content h3 {
  color: #333;
  margin-bottom: 10px;
}

.call-actions {
  margin-top: 20px;
}

.control-panel {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}

.input-group {
  margin-bottom: 15px;
}

.input-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

.input-group input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 16px;
}

.button-group {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.button-group button {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.btn-connect {
  background: #4caf50;
  color: white;
}
.btn-register {
  background: #2196f3;
  color: white;
}
.btn-call {
  background: #ff9800;
  color: white;
}
.btn-hangup {
  background: #f44336;
  color: white;
}
.btn-unregister {
  background: #9e9e9e;
  color: white;
}
.btn-answer {
  background: #4caf50;
  color: white;
}
.btn-reject {
  background: #f44336;
  color: white;
}

.button-group button:disabled {
  background: #cccccc;
  cursor: not-allowed;
}

.call-timer {
  text-align: center;
  font-size: 18px;
  font-weight: bold;
  color: #2196f3;
  margin: 20px 0;
}

.log-panel {
  background: #1e1e1e;
  color: white;
  padding: 15px;
  border-radius: 8px;
  margin-top: 20px;
}

.log-content {
  height: 200px;
  overflow-y: auto;
  background: #2d2d2d;
  padding: 10px;
  border-radius: 4px;
  margin-bottom: 10px;
  font-family: "Courier New", monospace;
  font-size: 12px;
}

.log-item {
  margin-bottom: 5px;
  padding: 2px 5px;
  border-radius: 3px;
}

.log-item.info {
  color: #ffffff;
}
.log-item.success {
  color: #4caf50;
}
.log-item.warning {
  color: #ff9800;
}
.log-item.error {
  color: #f44336;
}
.log-item.incoming {
  color: #ff9800;
  background: rgba(255, 152, 0, 0.1);
}

.btn-clear {
  background: #666;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
}

.btn-clear:hover {
  background: #777;
}

.audio-panel {
  margin: 20px 0;
  padding: 15px;
  background: #f9f9f9;
  border-radius: 8px;
}

.audio-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.audio-controls button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  background: #2196f3;
  color: white;
}
</style>